/**
 * Created by lional on 16/10/3.
 */

jGame.ControllerObject = jGame.GameObject.extend(/** @lends jGame.ControllerObject# */{

    _viewsStack:null,
    _listenersMap: null,

    ctor: function(){
        this._super();
        this._viewsStack = [];
        this._listenersMap = {};
        //cc.log("jGame.ControllerObject#ctor()");
    },

    onViewEnter: function (view) {

        this.trace(view, "onViewEnter");

        this._viewsStack.push(view);

        var controller = this;
        var childList = [];//diff controller callback child list
        var controllerList = [];//diff controller callback list
        jGame.ergodicAllNode(view, function (child) {
            if(child["getController"]) {
                var childController = child["getController"]();
                if(childController != controller && controllerList.indexOf(childController) < 0) {
                    childList.push(child);
                    controllerList.push(childController);
                }
            }
        });
        for(var childIndex in childList) {
            var child = childList[childIndex];
            var childController = child["getController"]();
            if(childController && typeof childController["onViewEnter"] === "function") {
                childController["onViewEnter"](child);
            }
        }

        jGame.eventManager.dispatchEvent(new jGame.EventCustom("jGame.ControllerObject.onViewEnter"));

    },

    onViewExit: function (view) {

        jGame.eventManager.dispatchEvent(new jGame.EventCustom("jGame.ControllerObject.onViewExit"));

        var controller = this;
        var childList = [];//diff controller callback child list
        var controllerList = [];//diff controller callback list
        jGame.ergodicAllNode(view, function (child) {
            if(child["getController"]) {
                var childController = child["getController"]();
                if(childController != controller && controllerList.indexOf(childController) < 0) {
                    childList.push(child);
                    controllerList.push(childController);
                }
            }
        });
        for(var childIndex in childList) {
            var child = childList[childIndex];
            var childController = child["getController"]();
            if (childController && typeof childController["onViewExit"] === "function") {
                childController["onViewExit"](childController.getView());
            }
        }
        this._viewsStack.pop();

        this.trace(view, "onViewExit");

    },

    popView: function () {
        var view = this.getView();
        if(view) {
            this.onViewExit(view);
            view.removeFromParent();
        }
    },

    getView: function () {
        var i = this._viewsStack.length;
        if (i === 0) {
            return this._viewsStack[i];
        } else {
            return this._viewsStack[i - 1];
        }
    },

    /**
     * Adds a Custom event listener. It will use a fixed priority of 1.
     *
     * var event = new jGame.EventCustom("game_custom_event");
     * event.setUserData(selfPointer._item2Count.toString());
     * jGame.eventManager.dispatchEvent(event);
     *
     * @param {string} eventName
     * @param {function} callback
     * @return {cc.EventListener} the generated event. Needed in order to remove the event from the dispatcher
     */
    addEventListener: function (eventName, callback) {
        if(this.getEventListeners(eventName)) {
            this.removeEventListener(eventName);
        }
        this._listenersMap[eventName] = cc.EventListener.create({
            event: cc.EventListener.CUSTOM,
            eventName: eventName,
            callback: callback
        });
        cc.eventManager.addListener(this._listenersMap[eventName], 1);
    },

    addAsyncEventListener: function (eventName, callback) {
        if(this.getEventListeners(eventName)) {
            this.removeEventListener(eventName);
        }
        var asyncCallBack = function(e){
            if(app) {
                var scene = app.getRunningScene();
                if(scene) {
                    var sceneCallBack = function (send, event) {
                        callback(event);
                    }
                    scene.runAction(cc.sequence(
                        cc.delayTime(0),
                        cc.callFunc(sceneCallBack, scene, e)  // If you want to pass a optional value, like "Hi!", then you should pass 'this' too
                    ));
                }
            }
        }
        this._listenersMap[eventName] = cc.EventListener.create({
            event: cc.EventListener.CUSTOM,
            eventName: eventName,
            callback: asyncCallBack
        });
        cc.eventManager.addListener(this._listenersMap[eventName], 1);
    },

    getEventListeners: function (eventName) {
        return this._listenersMap[eventName];
    },

    removeEventListener: function (eventName) {
        cc.eventManager.removeListener(this._listenersMap[eventName]);
    },

    removeAllEventListeners: function () {
        for (var index in this._listenersMap) {
            cc.eventManager.removeListener(this._listenersMap[index]);
        }
    },

    bindClick: function (viewName, clickName) {
        var view = viewName;
        if(typeof viewName === "string") {
            if(this.getView()) {
                view = jGame.findView(this.getView(), viewName);
            }else {
                view = app.getView(viewName);
            }
        }
        if(view && typeof view["setClickCallbackName"] === "function") {
            if(typeof view["setController"] === "function") {
                view["setController"](this);
            }
            view["setClickCallbackName"](clickName);
        }
    },

    bindTouch: function (viewName, touchName) {
        var view = viewName;
        if(typeof viewName === "string") {
            if(this.getView()) {
                view = jGame.findView(this.getView(), viewName);
            }else {
                view = app.getView(viewName);
            }
        }
        if(view && typeof view["setTouchCallbackName"] === "function") {
            if(typeof view["setController"] === "function") {
                view["setController"](this);
            }
            view["setTouchCallbackName"](touchName);
        }
    },

    bindSelect: function (viewName, touchName) {
        var view = viewName;
        if(typeof viewName === "string") {
            if(this.getView()) {
                view = jGame.findView(this.getView(), viewName);
            }else {
                view = app.getView(viewName);
            }
        }
        if(view && typeof view["setSelectCallbackName"] === "function") {
            if(typeof view["setController"] === "function") {
                view["setController"](this);
            }
            view["setSelectCallbackName"](touchName);
        }
    },

    bindOneByOne: function (viewName, touchBeganName, touchMovedName, touchEndedName, touchCancelledName, touchSwallowEnabled) {
        var view = viewName;
        if(typeof viewName === "string") {
            if(this.getView()) {
                view = jGame.findView(this.getView(), viewName);
            }else {
                view = app.getView(viewName);
            }
        }
        if(view && typeof view["setOneByOneCallbackName"] === "function") {
            if(typeof view["setController"] === "function") {
                view["setController"](this);
            }
            view["setOneByOneCallbackName"](touchBeganName, touchMovedName, touchEndedName, touchCancelledName, touchSwallowEnabled);
        }
    },

    bindAllAtOnce: function (viewName, touchBeganName, touchMovedName, touchEndedName, touchCancelledName) {
        var view = viewName;
        if(typeof viewName === "string") {
            if(this.getView()) {
                view = jGame.findView(this.getView(), viewName);
            }else {
                view = app.getView(viewName);
            }
        }
        if(view && typeof view["setAllAtOnceCallbackName"] === "function") {
            if(typeof view["setController"] === "function") {
                view["setController"](this);
            }
            view["setAllAtOnceCallbackName"](touchBeganName, touchMovedName, touchEndedName, touchCancelledName);
        }
    },
});